#include <iostream>
#include <vector>
#include <exception>
#include <execinfo.h>
#include <cstdlib>
#include <signal.h>
#include <cstdio>

using namespace std;

////////////////////////////////////////////////////
class ExceptionTracer
{
public:
    ExceptionTracer(void)
    {
        void *array[25];
        int nSize = backtrace(array, 25);
        char **symbols = backtrace_symbols(array, nSize);
        char cmd_str[512];
        for (int i = 0; i < nSize; ++i)
        {
            sprintf(cmd_str, "echo -n 'stack excep:';addr2line %p -e a.out | awk -F: '{if($2>0){print \"sed -n \"$2\"p \"$1}}' | sh", array[i]);
            system(cmd_str);
        }
        free(symbols);
    }
};

class SegmentationFault : 
    public ExceptionTracer, public exception
{
public:
    static int GetSignalNumber(void)
    {
        return SIGSEGV;
    }
};

template <class SignalExceptionClass>
class SignalTranslator
{
private:
    class SingleTonTranslator
    {
    public:
        SingleTonTranslator(void)
        {
            ::signal(SignalExceptionClass::GetSignalNumber(), SignalHandler);
        }
        static void SignalHandler(int)
        {
            throw SignalExceptionClass();
        }
    };

public:
    SignalTranslator(void)
    {
        static SingleTonTranslator s_objTranslator;
    }
};

class ExceptionHandler
{
private:
    class SingleTonHandler
    {
    public:
        SingleTonHandler(void)
        {
            set_terminate(Handler);
        }
        static void Handler(void)
        {
            try
            {
                throw;
            }
            catch (SegmentationFault &)
            {
                cout << "SegmentationFault" << endl;
            }
            catch (...)
            {
                cout << "unknown Exception" << endl;
            }
        }
    };

public:
    ExceptionHandler(void)
    {
        static SingleTonHandler s_objHandler;
    }
};

class Temp
{
public:
    int func(void)
    {
//        try
        {
            vector<int> vc;
            vc[1] = 0;
            return 0;
        }
//        catch (...)
//        {
//            cout << "\nfunc exception" << endl;
//            return -1;
//        }
    }
};

SignalTranslator<SegmentationFault> g_objSegmentationExceptionTransltor;
//int main(void)
//{
//    try
//    {
//        Temp t;
//        t.func();
//    }
//    catch (...)
//    {
//        cout << "\nfunc exception" << endl;
//        return -1;
//    }
//    cout << "main end" << endl;
//    return 0;
//}

